/**
 * 文件名：@JsonView.java <br/>
 * 包名：cn.efunbox.afw.web.mvc.view <br/>
 * 项目名：afw-web <br/>
 * @author xtwin <br/>
 */
package cn.efunbox.afw.web.mvc.view;

import java.util.Collections;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

import cn.efunbox.afw.web.entity.HttpResult;
import cn.efunbox.afw.web.mvc.exception.ExceptionModelResolver;
import cn.efunbox.afw.web.util.AfwWebConstant;

/**
 * 类名：JsonView  <br />
 *
 * 功能：json视图
 *
 * @author xtwin <br />
 * 创建时间：2016年8月5日 上午2:12:53  <br />
 * @version 2016年8月5日
 */
public class JsonView extends MappingJackson2JsonView {
	
	// 异常模型解析器
	protected ExceptionModelResolver exceptionModelResolver;
	
	/**
	 * 构造方法
	 */
	public JsonView() {
		this(Jackson2ObjectMapperBuilder.json()

			// 不忽略对象属性中的null值
			.serializationInclusion(Include.ALWAYS)

				// 忽略map中的null值
			.featuresToDisable(SerializationFeature.WRITE_NULL_MAP_VALUES,
					SerializationFeature.WRITE_EMPTY_JSON_ARRAYS)
			.build());
	}
	
	/**
	 * 构造方法
	 */
	public JsonView(ObjectMapper objectMapper) {

		super(objectMapper);

		// 提取该值
		setModelKey(AfwWebConstant.KEY_RETURN_VALUE);
		// 提取单个值
		setExtractValueFromSingleKeyModel(true);
	}
	
	/**
	 * 功能: <br/>
	 * 
	 * 重写：xtwin <br/>
	 * 
	 * @version ：2016年8月5日 上午3:03:06<br/>
	 * 
	 * @param model
	 * @param request
	 * @param response
	 * @return <br/>
	 * @see org.springframework.web.servlet.view.AbstractView#createMergedOutputModel(java.util.Map, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	@Override
	protected Map<String, Object> createMergedOutputModel(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) {
		
		// 取出结果对象
		Object ret = model.get(AfwWebConstant.KEY_RETURN_VALUE);
		
		// TODO 这里先简单的对该类型进行处理，待实现更灵活的配置
		if (ret instanceof HttpResult) {
			// http结果对象
			HttpResult<?> httpResult = (HttpResult<?>) ret;
			
			// 异常处理
			Exception ex = httpResult.getException();
			HttpResult<?> exResult = null;
			if (null != ex) {
				// 结果
				exResult = exceptionModelResolver.resolve(request, response, ex);
				ret = exResult.getBody();
			} else {
				ret = httpResult.getBody();
			}
			
			if (null != httpResult.getStatus()) {
				// http状态码
				response.setStatus(httpResult.getStatus());
			} else if (null != exResult) {
				// 默认异常状态码
				response.setStatus(exResult.getStatus());
			}
			
			// 响应头
			httpResult.getHeaders().forEach((name, value) -> response.addHeader(name, value));
		}
		
		// 返回结果对象
		return Collections.singletonMap(AfwWebConstant.KEY_RETURN_VALUE, ret);
	}

	/**
	 * @version 2016年8月5日-上午3:20:09
	 */
	public void setExceptionModelResolver(ExceptionModelResolver exceptionModelResolver) {
		this.exceptionModelResolver = exceptionModelResolver;
	}
}